package cate.game.activity.dailysign;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.table.res.sign.addup.DailySignAddUpRow;
import cate.common.table.res.sign.addup.DailySignAddUpSheet;
import cate.common.table.res.sign.common.DailySignCommonRow;
import cate.common.table.res.sign.item.DailySignItemRow;
import cate.game.role.Role;
import cp.solution.util.time.TimeSpanCheck;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.dailysign.msg.DailySignInfoResp;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashMap;
import java.util.Map;

@NoteClass("签到")
public class DailySignActivity extends RoleActivitySingle {
    @NoteField(value = "上次签到的时间")
    public long lastSignTime;
    @NoteField(value = "上次额外签到的时间")
    public long lastExtraSignTime;
    @NoteField(value = "当月签到次数")
    public int signTimes;
    @NoteField(value = "签到奖励状态", detail = "配置ID => 是否已经领取")
    public Map<Integer, Boolean> signRewardStates;

    // 以下为不清空的数据
//    @NoteField(value = "累计签到次数")
//    public int addUpSignTimes;
//    @NoteField(value = "累计签到奖励状态", detail = "配置ID => 是否已经领取")
//    public Map<Integer, Boolean> addUpRewardStates;


    @Override
    public void initialize(Role role) {
        super.initialize(role);
        role.getActivity().registerRecharge(this, (pay) -> this.initSend());
    }

    @Override
    public void onEnter() {
        super.onEnter();
        if (TimeSpanCheck.spanDay(lastSignTime)) {
            signTimes++;
            lastSignTime = game().time.now();
        }
    }

    @Override
    public void excelCheck() {
        DailySignAddUpSheet configSheet = getAddUpSheet();
        if (configSheet == null) {
            return;
        }
        if (signRewardStates == null) {
            signRewardStates = new HashMap<>();
        }
        Map<Integer, DailySignItemRow> signConfigs = getAllItemConfigs();
        signRewardStates.entrySet().removeIf(kv -> signConfigs.get(kv.getKey()) == null);
        if (signRewardStates.size() == 0) {
            signTimes = 0;
        }
        for (DailySignItemRow configRow : signConfigs.values()) {
            if (!signRewardStates.containsKey(configRow.excelId)) {
                signRewardStates.put(configRow.excelId, false);
            }
        }
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        logger.info("每日签到跨天");
        if (silence) {
            if (TimeSpanCheck.spanDay(lastSignTime)) {
                signTimes++;
                lastSignTime = game().time.now();
            }
        } else {
            signTimes++;
            lastSignTime = game().time.now();
        }
        if (!silence) {
            noticeUpdate();
        }
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        lastSignTime = 0;
        lastExtraSignTime = 0;
        signTimes = 0;
        if (signRewardStates != null) {
            signRewardStates.clear();
        }
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    /**
     * 获取基础配置
     */
    @JsonIgnore
    private DailySignCommonRow getCommonConfig() {
        switch (funcId()) {
            case GDFunc.ACT_DAILY_SIGN:
                return role.getGame().table.signDaily.common.get(configTid());
            default:
                return null;
        }
    }

    /**
     * 获取当前奖励分组
     */
    @JsonIgnore
    private int getCurrentGroup() {
        DailySignCommonRow config = getCommonConfig();
        if (config != null) {
            return config.group;
        }
        return 0;
    }

    /**
     * 获取当前分组的签到奖励配置列表
     */
    @JsonIgnore
    private Map<Integer, DailySignItemRow> getAllItemConfigs() {
        Map<Integer, DailySignItemRow> ret = new HashMap<>();
        switch (funcId()) {
            case GDFunc.ACT_DAILY_SIGN: {
                role.getGame().table.signDaily.item.getList().forEach(config -> {
                    if (config.group == getCurrentGroup()) {
                        ret.put(config.excelId, config);
                    }
                });
            }
            break;
            default:
                break;
        }
        return ret;
    }

    /**
     * 获取对应天的奖励配置
     */
    @JsonIgnore
    private DailySignItemRow getItemConfig(int day) {
        switch (funcId()) {
            case GDFunc.ACT_DAILY_SIGN:
                int configKey = DailySignItemRow.generateId(getCurrentGroup(), day);
                return role.getGame().table.signDaily.item.get(configKey);
            default:
                return null;
        }
    }

    /**
     * 获取累计奖励Sheet
     */
    @JsonIgnore
    private DailySignAddUpSheet getAddUpSheet() {
        switch (funcId()) {
            case GDFunc.ACT_DAILY_SIGN:
                return role.getGame().table.signDaily.addUp;
            default:
                return null;
        }
    }

    /**
     * 获取累计奖励配置
     */
    @JsonIgnore
    private DailySignAddUpRow getAddUpConfig(int tid) {
        switch (funcId()) {
            case GDFunc.ACT_DAILY_SIGN:
                return role.getGame().table.signDaily.addUp.get(tid);
            default:
                return null;
        }
    }

    /**
     * 获取累计签到最大奖励次数
     */
    @JsonIgnore
    private int getMaxAddUpSignTimes() {
        switch (funcId()) {
            case GDFunc.ACT_DAILY_SIGN:
                return role.getGame().table.signDaily.getMaxAddUpSignTimes();
            default:
                return 0;
        }
    }

    /**
     * 获取签到最大次数
     */
    @JsonIgnore
    private int getMaxSignDay() {
        switch (funcId()) {
            case GDFunc.ACT_DAILY_SIGN:
                return role.getGame().table.signDaily.item.getMaxDay(getCurrentGroup());
            default:
                return 0;
        }
    }

    /**
     * 签到
     *
     * @return 签到结果 携带自身数据
     */
    public EcResult<DailySignActivity> onSignUp(int day) {
        EcResult<DailySignActivity> r = new EcResult<>();
        r.data = this;
        DailySignItemRow configRow = getItemConfig(day);
        if (configRow == null) {
            return r.fail("未找到配置1");
        }
        if (!signRewardStates.containsKey(configRow.excelId)) {
            return r.fail("未找到配置2");
        }
        if (day > signTimes) {
            return r.fail("签到天数不足");
        }
        if (signRewardStates.get(configRow.excelId)) {
            return r.fail("已进行签到");
        }
        MixRes mixRes = new MixRes(configRow.rewardStr);
        if (mixRes.isEmpty()) {
            return r.fail(String.format("签到 基础配置ID=%d 奖励为空!", configRow.excelId));
        }
        // 发放奖励
        EcResult<?> r_res = new MixResAdder().setRes(mixRes)
                .setOperation(GDOperation.SIGN_DAILY_SIGN_REWARD)
                .setOperationSub(configRow.excelId)
                .setDialogReward(true)
                .exe(role);
        if (!r_res.ok()) {
            return r.fail(r_res.message);
        }
        // 记录签到
        signRewardStates.put(configRow.excelId, true);
        // 记录累计签到次数
        role.getHistory().action.onSignUp();
        return r.success();
    }

    /**
     * 额外签到
     *
     * @return 额外签到结果 EcResult无数据
     */
    public EcResult<DailySignActivity> onExtraSignUp() {
        EcResult<DailySignActivity> r = new EcResult<>();
        r.data = this;
        DailySignCommonRow config = getCommonConfig();
        if (config == null) {
            return r.fail("未找到配置");
        }
        if (config.extra == 0) {
            return r.fail("不支持额外签到");
        }
        if (TimeSpanCheck.spanDay(role.getPay().lastPayTime)) {
            return r.fail("今日尚未充值");
        }
        int dayMax = getMaxSignDay();
        int checkDay = Math.min(signTimes, dayMax);
        DailySignItemRow checkConfig = getItemConfig(checkDay);
        if (checkConfig == null || !signRewardStates.containsKey(checkConfig.excelId)) {
            return r.fail("未找到配置2");
        }
        if (!signRewardStates.get(checkConfig.excelId)) {
            return r.fail("请先完成今日签到");
        }
        if (!TimeSpanCheck.spanDay(lastExtraSignTime)) {
            return r.fail("今日已进行额外签到");
        }
        DailySignItemRow configRow = getItemConfig(signTimes);
        if (configRow == null) {
            return r.fail("未找到配置");
        }
        MixRes mixRes = new MixRes(configRow.rewardStr);
        if (mixRes.isEmpty()) {
            return r.fail(String.format("签到 基础配置ID=%d 奖励为空!", configRow.excelId));
        }
        // 发放奖励
        EcResult<?> r_res = new MixResAdder().setRes(mixRes)
                .setOperation(GDOperation.SIGN_DAILY_SIGN_REWARD_EXTRA)
                .setOperationSub(configRow.excelId)
                .setDialogReward(true)
                .exe(role);
        if (!r_res.ok()) {
            return r.fail(r_res.message);
        }
        lastExtraSignTime = game().time.now();
        return r.success();
    }

//    /**
//     * 领取累计签到奖励
//     *
//     * @param addUpId 累计配置ID
//     * @return 领奖结果 EcResult无数据
//     */
//    public EcResult<DailySignActivity> onGetAddUpReward(int addUpId) {
//        EcResult<DailySignActivity> r = new EcResult<>();
//        r.data = this;
//        DailySignAddUpRow configRow = getAddUpConfig(addUpId);
//        if (configRow == null) {
//            return r.fail("未找到配置");
//        }
//        if (!addUpRewardStates.containsKey(addUpId)) {
//            excelCheck();
//        }
//        // 检测是否已领取
//        boolean boGet = addUpRewardStates.get(addUpId);
//        if (boGet) {
//            return r.fail("奖励已领取");
//        }
//        // 检测是否满足领取条件
//        if (addUpSignTimes < configRow.needSignTimes) {
//            return r.fail("签到天数不足");
//        }
//        MixRes mixRes = new MixRes(configRow.rewardStr);
//        if (mixRes.isEmpty()) {
//            return r.fail(String.format("签到 累计配置ID=%d 奖励为空!", configRow.id));
//        }
//        EcResult<?> r_res = new MixResAdder().setRes(mixRes)
//                .setOperation(GDOperation.SIGN_DAILY_ADD_UP_REWARD)
//                .setOperationSub(addUpId)
//                .setDialogReward(true)
//                .exe(role);
//        if (!r_res.ok()) {
//            return r.fail(r_res.message);
//        }
//        // 发放奖励
//        addUpRewardStates.put(addUpId, true);
//        // 检测重置累计奖励
//        boolean boAllGet = true;
//        for (Boolean state : addUpRewardStates.values()) {
//            if (!state) {
//                boAllGet = false;
//                break;
//            }
//        }
//        if (boAllGet) {
//            addUpSignTimes = Math.max(0, addUpSignTimes - getMaxAddUpSignTimes());
//            addUpRewardStates.clear();
//            excelCheck();
//        }
//        return r.success();
//    }

    public void noticeUpdate() {
        role.sendNow(new DailySignInfoResp(this));
    }

    @Override
    public void onMonthSpan(boolean silence) {
        /*logger.info("每日签到跨月");
        super.onMonthSpan(silence);
        signTimes = 0;
        signRewardStates.clear();
        excelCheck();
        if (silence) {
            if (TimeSpanCheck.spanDay(lastSignTime)) {
                signTimes++;
                lastSignTime = game().time.now();
                //跨月后，额外签到时间改为前一天
                lastExtraSignTime = game().time.now() - TimeTool.TimeCons.DAY;
            }
        } else {
            signTimes++;
            lastSignTime = game().time.now();
            lastExtraSignTime = game().time.now() - TimeTool.TimeCons.DAY;
        }
        if (!silence) {
            noticeUpdate();
        }*/
    }

}
